package br.eng.eliseu.gwt.aconchego.camera.client.ui.usuario;

import java.util.ArrayList;
import java.util.List;

import br.eng.eliseu.gwt.aconchego.camera.client.service.UsuarioService;
import br.eng.eliseu.gwt.aconchego.camera.client.service.UsuarioServiceAsync;
import br.eng.eliseu.gwt.aconchego.camera.client.ui.component.EditAsyncCallback;
import br.eng.eliseu.gwt.aconchego.camera.client.ui.component.EnumListBox;
import br.eng.eliseu.gwt.aconchego.camera.client.ui.component.MaskedTextBox;
import br.eng.eliseu.gwt.aconchego.camera.module.AcessoCam;
import br.eng.eliseu.gwt.aconchego.camera.module.Camera;
import br.eng.eliseu.gwt.aconchego.camera.module.GrupoEnum;
import br.eng.eliseu.gwt.aconchego.camera.module.StatusEnum;
import br.eng.eliseu.gwt.aconchego.camera.shared.StringUtil;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.TimeZone;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class UsuarioEdit extends Composite {

	private static UsuarioViewUiBinder uiBinder = GWT.create(UsuarioViewUiBinder.class);
	interface UsuarioViewUiBinder extends UiBinder<Widget, UsuarioEdit> {}
	
	private final UsuarioServiceAsync usuarioService = GWT.create(UsuarioService.class);
	private EditAsyncCallback<AcessoCam> callback;

	
//	@UiField ListBox statusLBox;
	@UiField (provided = true)EnumListBox<StatusEnum> statusLBox;
//	@UiField (provided = true)ListBox statusLBox;
	@UiField TextBox nomeTBox;
	@UiField TextBox emailTBox;
	@UiField PasswordTextBox senhaTBox;
	@UiField (provided = true)EnumListBox<GrupoEnum> grupoLBox;
//	@UiField (provided = true)ListBox grupoLBox;
	@UiField MaskedTextBox periodoInicioTBox;
	@UiField MaskedTextBox periodoFinalTBox;
	@UiField (provided = true)ListBox camerasLBox = new ListBox(true);
	@UiField Button gravaButton;
	@UiField Button fecharButton;
	@UiField CheckBox enviaEmailCBox;
	@UiField Label msgErroLabel;

	private AcessoCam usuarioLogin;
	private AcessoCam acesso;
	
	private DateTimeFormat fmtHora;
	
	public UsuarioEdit(AcessoCam usuarioLogin) {
		
		statusLBox = new EnumListBox<StatusEnum>(StatusEnum.class);
		grupoLBox = new EnumListBox<GrupoEnum>(GrupoEnum.class);
		initWidget(uiBinder.createAndBindUi(this));
		
		this.usuarioLogin = usuarioLogin;
		
		periodoInicioTBox.setMask("99:99");
		periodoFinalTBox.setMask("99:99");
		
		fmtHora = DateTimeFormat.getFormat("HH:mm");
		
		if (this.usuarioLogin==null){
			//--- Primeiro usuario
//			grupoLBox.setSelectedValue(GrupoEnum.ADMINISTRADOR);
			grupoLBox.setEnabled(false);
		}
		
		listPopulaCamerasAsync();
		
	}

	@UiHandler("fecharButton")
	void onFecharButtonClick(ClickEvent event) {
		if (getCallback()!=null){
			getCallback().onCancel();
		}
	}
	
	@UiHandler("gravaButton")
	void onGravaButtonClick(ClickEvent event) {
		if (checaCampoEmBranco()){
			leView();
			GravaAsync();
		}
	}
	
	private void GravaAsync(){
		
		usuarioService.gravaAcesso( getAcesso(), enviaEmailCBox.getValue(), new AsyncCallback<AcessoCam>(){

			public void onSuccess(AcessoCam acesso) {
				if (getCallback()!=null){
					getCallback().onOk(acesso);
				}
			}
			
			public void onFailure(Throwable erro) {
				showErro(erro.getMessage());
//				if (getCallback()!=null){
//					getCallback().onCancel();
//				}
			}

		});
		
	}
	
	private void leView(){
		StatusEnum status = statusLBox.getSelectedValue();
		getAcesso().setStatus(status);
		getAcesso().getUsuario().setNome(nomeTBox.getValue());
		getAcesso().getUsuario().setEmail(emailTBox.getValue());
		getAcesso().getUsuario().setSenha(senhaTBox.getValue());
		getAcesso().setGrupo(grupoLBox.getSelectedValue());
		if ( !"".equals(periodoInicioTBox.getValue())){
			getAcesso().setPeriodoInicio(fmtHora.parse(periodoInicioTBox.getValue()));
		}
		if ( !"".equals(periodoFinalTBox.getValue())){
			getAcesso().setPeriodoFim(fmtHora.parse(periodoFinalTBox.getValue()));
		}
		
		List<Camera> selectedItems = new ArrayList<Camera>();
	    for (int i = 0; i < camerasLBox.getItemCount(); i++) {
	        if (camerasLBox.isItemSelected(i)) {
	        	Camera c = new Camera();
	        	c.setId(StringUtil.pegaValorCodigoInt(camerasLBox.getItemText(i), "-"));
	            selectedItems.add(c);
	        }
	    }
		getAcesso().setCameras(selectedItems);
	}
	
	private void populaView(){
		if (getAcesso()!=null){
			if (getAcesso().getUsuario().getEmail()!=null){
				statusLBox.setSelectedValue(getAcesso().getStatus());
				nomeTBox.setValue(StringUtil.branco(getAcesso().getUsuario().getNome()));
				emailTBox.setValue(StringUtil.branco(getAcesso().getUsuario().getEmail()));
				senhaTBox.setValue(StringUtil.branco(getAcesso().getUsuario().getSenha()));
				grupoLBox.setSelectedValue(getAcesso().getGrupo());
				if ( getAcesso().getPeriodoInicio()==null ){
					periodoInicioTBox.setValue("");
				} else {
//					periodoInicioTBox.setValue( fmtHora.format(getAcesso().getPeriodoInicio()) );
					periodoInicioTBox.setValue( fmtHora.format(getAcesso().getPeriodoInicio(), TimeZone.createTimeZone(180)) );
					
				}
				if ( getAcesso().getPeriodoFim()==null ){
					periodoFinalTBox.setValue("");
				} else {
					periodoFinalTBox.setValue( fmtHora.format(getAcesso().getPeriodoFim(), TimeZone.createTimeZone(180)) );
				}

				enviaEmailCBox.setValue(false);
				// --- Limpa selecao
				for(int i=0;i<camerasLBox.getItemCount();i++){
					camerasLBox.setItemSelected(i, false);
				}

				// --- Seleciona as cameras do usuario
				if (getAcesso().getCameras()!=null){
					for (Camera c : getAcesso().getCameras()) {
						for(int i=0;i<camerasLBox.getItemCount();i++){
							if(camerasLBox.getItemText(i).equals(c.getId()+"-"+c.getNome())){
								camerasLBox.setItemSelected(i, true);
								break;
							}
						}
					}
				}
				
			}
		}
	}
	
	private void listPopulaCamerasAsync(){
		camerasLBox.clear();
		usuarioService.getCameras(new AsyncCallback<List<Camera>>(){

			public void onSuccess(List<Camera> listaCameras) {
				camerasLBox.clear();
				for (Camera c : listaCameras) {
					camerasLBox.addItem(c.getId()+ "-" + c.getNome());
				}
				populaView();
			}
			
			public void onFailure(Throwable arg0) {
				// TODO Auto-generated method stub
				
			}
		});
	
	}
	
	private Boolean checaCampoEmBranco(){
		showErro("");
		
		if ( statusLBox==null | statusLBox.getSelectedIndex()<0 ){
			showErro("Selecione um Status");
			return false;
		}
		if ( nomeTBox==null || "".equals(nomeTBox.getValue()) ){
			showErro("Informe o Nome do usuario");
			return false;
		}
		if ( emailTBox==null || "".equals(emailTBox.getValue()) ){
			showErro("Informe o e-Mail do usuario");
			return false;
		}
		if ( senhaTBox==null || "".equals(senhaTBox.getValue()) ){
			showErro("Informe uma Senha para o usuario");
			return false;
		}
		if ( grupoLBox==null || grupoLBox.getSelectedIndex()<0 ){
			showErro("Selecione um Grupo");
			return false;
		}
		if ( grupoLBox.getItemText(grupoLBox.getSelectedIndex()).equals(GrupoEnum.USUARIO) || 
			 grupoLBox.getItemText(grupoLBox.getSelectedIndex()).equals(GrupoEnum.CONVIDADO) ){

			if ( periodoInicioTBox==null || "".equals(periodoInicioTBox.getValue()) ){
				showErro("Informe o Inicio do periodo liberado");
				return false;
			}
			if ( periodoFinalTBox==null || "".equals(periodoFinalTBox.getValue()) ){
				showErro("Informe o Final do periodo liberado");
				return false;
			}
		}
		
		return true;
	}

	private void showErro(String msg) {
		msgErroLabel.setText(msg);
	}

	public EditAsyncCallback<AcessoCam> getCallback() {
		return callback;
	}

	public void setCallback(EditAsyncCallback<AcessoCam> callback) {
		this.callback = callback;
	}

	public AcessoCam getAcesso() {
		return acesso;
	}

	public void setAcesso(AcessoCam acesso) {
		this.acesso = acesso;
		populaView();
	}

}
